package fhq.hcmute.edu.vn.gui;

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Frame;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;

import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JTextPane;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

import fhq.hcmute.edu.vn.config.AppConfig;
import fhq.hcmute.edu.vn.config.PictureFrameSetting;
import fhq.hcmute.edu.vn.language.Language;
import fhq.hcmute.edu.vn.language.LanguageFactory;
import fhq.hcmute.edu.vn.language.Language_EN;
import fhq.hcmute.edu.vn.network.ComputerInfos;
import fhq.hcmute.edu.vn.network.NetworkUtil;
import fhq.hcmute.edu.vn.network.Server;
import fhq.hcmute.edu.vn.util.BarcodeUtil;
import javax.swing.JToolBar;

public class ServerGUI extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private JPanel contentPane;
	private JLabel lblHostName;
	private static JLabel lblBarcode;
	public static JButton btnStopServer;
	public static JButton btnStartServer;
	private static JTextPane txtHostName;
	private static JTextPane txtIPAddress;
	private static JTextPane txtPort;
	private static JTextPane txtPassword;
	private static ComputerInfos serverInfo;
	private static ImageIcon barcode;
	private static BufferedImage bufferedImage;
	private static Frame frame;
	private static Server server;
	private Language language;

	public static final Server getServer() {
		return server;
	}

	public static void setServer(Server server) {
		ServerGUI.server = server;
	}

	public static final Frame getFrame() {
		return frame;
	}

	/**
	 * Launch the application.
	 */
	@SuppressWarnings("unused")
	private static ServerSocket skKiemTra;

	public static void main(final String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					skKiemTra = new ServerSocket(9999, 10, InetAddress
							.getLocalHost());
					ServerGUI frame = new ServerGUI();
					frame.setVisible(true);
					frame.setLocationRelativeTo(null);
					updateServerInfos();
				} catch (java.net.BindException b) {
					JOptionPane.showMessageDialog(frame, "Already Running...");
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	private JRadioButtonMenuItem rbMenuEnglish;
	private JRadioButtonMenuItem rbMenuTiengviet;
	private JMenu menuLanguages;
	private JMenuItem menuPickNetworkCard;
	private JMenuItem menuListDevide;
	private JMenuItem menuExit;
	private JMenu menuHelp;
	private JMenuItem menuHelpContents;
	private JMenuItem menuAbout;
	private JLabel lblPassword;
	private JLabel lblPort;
	private JLabel lblIpAddress;
	private JMenu menuOption;
	private JRadioButtonMenuItem rdbAutomatic;
	private JRadioButtonMenuItem rdbBlanced;
	private JRadioButtonMenuItem rdbQuality;
	private JRadioButtonMenuItem rdbSpeed;
	private JRadioButtonMenuItem rdbUltraQuality;
	private JMenu menuImageQuality;
	private JCheckBoxMenuItem cbSaveImages;
	private JMenu menuPictureFrame;
	public static JButton btnMinimize;

	/**
	 * Create the frame.
	 */
	public ServerGUI() {
		frame = JOptionPane.getFrameForComponent(ServerGUI.this);
		language = LanguageFactory.getInstance().getLanguage();
		setTitle("Trackpad Emulator Server");
		setFont(new Font("Times New Roman", Font.PLAIN, 13));
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 640, 351);

		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		menuOption = new JMenu(language.menuOption());
		menuBar.add(menuOption);

		menuPickNetworkCard = new JMenuItem(language.menuPickNetworkCard());
		menuPickNetworkCard.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				NetworkDialog networkDialog = new NetworkDialog(frame, true);
				networkDialog.setVisible(true);
				if (networkDialog.getDialogResult() == NetworkDialog.OK) {
					updateServerInfos();
				}
			}
		});
		menuOption.add(menuPickNetworkCard);

		menuListDevide = new JMenuItem(language.menuListDevide());
		menuListDevide.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent arg0) {
				ListDevicesDialog listDevicesDialog = new ListDevicesDialog(
						frame, true);
				listDevicesDialog.setVisible(true);
			}
		});
		ButtonGroup directionGroup = new ButtonGroup();
		menuLanguages = new JMenu(language.menuLanguage());
		menuOption.add(menuLanguages);

		rbMenuEnglish = new JRadioButtonMenuItem("English");
		menuLanguages.add(rbMenuEnglish);
		directionGroup.add(rbMenuEnglish);
		rbMenuTiengviet = new JRadioButtonMenuItem("Tiếng Việt");
		menuLanguages.add(rbMenuTiengviet);
		directionGroup.add(rbMenuTiengviet);

		menuPictureFrame = new JMenu(language.menuPictureFrame());
		menuOption.add(menuPictureFrame);
		cbSaveImages = new JCheckBoxMenuItem(language.menuSaveImages());
		boolean isCheck = AppConfig.getInstance().getPictureFrameSetting()
				.isSavePicture();
		cbSaveImages.setSelected(isCheck);
		cbSaveImages.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				AppConfig.getInstance().getPictureFrameSetting()
						.setSavePicture(cbSaveImages.isSelected());
				AppConfig.getInstance().commit();
			}
		});
		menuPictureFrame.add(cbSaveImages);
		menuImageQuality = new JMenu(language.menuScaleMathod());
		menuPictureFrame.add(menuImageQuality);

		rdbAutomatic = new JRadioButtonMenuItem(language.menuScaleAutomatic());
		rdbAutomatic.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				AppConfig.getInstance().getPictureFrameSetting()
						.setScaleMethod(PictureFrameSetting.AUTOMATIC);
				AppConfig.getInstance().commit();
			}
		});
		rdbBlanced = new JRadioButtonMenuItem(language.menuScaleBlanced());
		rdbBlanced.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				AppConfig.getInstance().getPictureFrameSetting()
						.setScaleMethod(PictureFrameSetting.BALANCED);
				AppConfig.getInstance().commit();
			}
		});
		rdbQuality = new JRadioButtonMenuItem(language.menuScaleQuality());
		rdbQuality.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				AppConfig.getInstance().getPictureFrameSetting()
						.setScaleMethod(PictureFrameSetting.QUALITY);
				AppConfig.getInstance().commit();
			}
		});
		rdbSpeed = new JRadioButtonMenuItem(language.menuScaleSpeed());
		rdbSpeed.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				AppConfig.getInstance().getPictureFrameSetting()
						.setScaleMethod(PictureFrameSetting.SPEED);
				AppConfig.getInstance().commit();
			}
		});
		rdbUltraQuality = new JRadioButtonMenuItem(
				language.menuScaleUltraQuality());
		rdbUltraQuality.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				AppConfig.getInstance().getPictureFrameSetting()
						.setScaleMethod(PictureFrameSetting.ULTRA_QUALITY);
				AppConfig.getInstance().commit();
			}
		});

		int method = AppConfig.getInstance().getPictureFrameSetting()
				.getScaleMethod();
		if (method == PictureFrameSetting.AUTOMATIC) {
			rdbAutomatic.setSelected(true);
		} else if (method == PictureFrameSetting.BALANCED) {
			rdbBlanced.setSelected(true);
		} else if (method == PictureFrameSetting.QUALITY) {
			rdbQuality.setSelected(true);
		} else if (method == PictureFrameSetting.SPEED) {
			rdbSpeed.setSelected(true);
		} else if (method == PictureFrameSetting.ULTRA_QUALITY) {
			rdbUltraQuality.setSelected(true);
		}
		ButtonGroup methodScale = new ButtonGroup();
		menuImageQuality.add(rdbAutomatic);
		methodScale.add(rdbAutomatic);
		menuImageQuality.add(rdbBlanced);
		methodScale.add(rdbBlanced);
		menuImageQuality.add(rdbQuality);
		methodScale.add(rdbQuality);
		menuImageQuality.add(rdbSpeed);
		methodScale.add(rdbSpeed);
		menuImageQuality.add(rdbUltraQuality);
		methodScale.add(rdbUltraQuality);

		menuOption.add(menuListDevide);

		rbMenuEnglish.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				LanguageFactory.setDefaultLanguage(Language.ENGLISH);
				updateLanguages();
			}
		});
		rbMenuTiengviet.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				LanguageFactory.setDefaultLanguage(Language.VIETNAMESE);
				updateLanguages();
			}
		});
		if (language instanceof Language_EN) {
			rbMenuEnglish.setSelected(true);
		} else {
			rbMenuTiengviet.setSelected(true);
		}

		menuExit = new JMenuItem(language.btnExit());
		menuOption.add(menuExit);
		menuHelp = new JMenu(language.menuHelp());
		// menuBar.add(menuHelp);

		menuHelpContents = new JMenuItem(language.menuHelpContents());
		menuHelp.add(menuHelpContents);

		menuAbout = new JMenuItem(language.menuAbout());
		menuHelp.add(menuAbout);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		lblHostName = new JLabel(language.lblHostName());
		lblHostName.setHorizontalAlignment(SwingConstants.RIGHT);
		lblHostName.setFont(new Font("Times New Roman", Font.PLAIN, 18));
		lblHostName.setBounds(289, 34, 112, 22);
		contentPane.add(lblHostName);

		txtHostName = new JTextPane();
		txtHostName.setEditable(false);
		txtHostName.setBackground(SystemColor.control);
		txtHostName.setFont(new Font("Times New Roman", Font.PLAIN, 18));
		txtHostName.setBounds(411, 31, 205, 25);
		contentPane.add(txtHostName);
		lblIpAddress = new JLabel(language.lblIpAddress());
		lblIpAddress.setHorizontalAlignment(SwingConstants.RIGHT);
		lblIpAddress.setFont(new Font("Times New Roman", Font.PLAIN, 18));
		lblIpAddress.setBounds(289, 67, 112, 22);
		contentPane.add(lblIpAddress);

		txtIPAddress = new JTextPane();
		txtIPAddress.setEditable(false);
		txtIPAddress.setBackground(SystemColor.control);
		txtIPAddress.setFont(new Font("Times New Roman", Font.PLAIN, 18));
		txtIPAddress.setBounds(411, 64, 205, 25);
		contentPane.add(txtIPAddress);

		btnStartServer = new JButton(language.btnStartServer());
		btnStartServer.addActionListener(onCLickStartButton);
		btnStartServer.setFont(new Font("Times New Roman", Font.PLAIN, 18));
		btnStartServer.setBounds(303, 178, 130, 30);
		contentPane.add(btnStartServer);

		btnStopServer = new JButton(language.btnStopServer());

		btnStopServer.addActionListener(onClickStopButton);
		btnStopServer.setFont(new Font("Times New Roman", Font.PLAIN, 18));
		btnStopServer.setBounds(486, 178, 130, 30);
		contentPane.add(btnStopServer);
		lblPort = new JLabel(language.lblPort());
		lblPort.setHorizontalAlignment(SwingConstants.RIGHT);
		lblPort.setFont(new Font("Times New Roman", Font.PLAIN, 18));
		lblPort.setBounds(289, 100, 112, 22);
		contentPane.add(lblPort);

		txtPort = new JTextPane();
		txtPort.setEditable(false);
		txtPort.setBackground(SystemColor.control);
		txtPort.setFont(new Font("Times New Roman", Font.PLAIN, 18));
		txtPort.setBounds(411, 97, 205, 25);
		contentPane.add(txtPort);

		lblPassword = new JLabel(language.lblPassword());
		lblPassword.setHorizontalAlignment(SwingConstants.RIGHT);
		lblPassword.setFont(new Font("Times New Roman", Font.PLAIN, 18));
		lblPassword.setBounds(289, 133, 112, 22);
		contentPane.add(lblPassword);

		txtPassword = new JTextPane();
		txtPassword.setEditable(false);
		txtPassword.setBackground(SystemColor.control);
		txtPassword.setFont(new Font("Times New Roman", Font.PLAIN, 18));
		txtPassword.setBounds(411, 130, 205, 25);
		contentPane.add(txtPassword);
		lblBarcode = new JLabel(barcode, SwingConstants.CENTER);
		lblBarcode.setBounds(10, 11, 250, 250);
		Border border = LineBorder.createBlackLineBorder();
		lblBarcode.setBorder(border);
		contentPane.add(lblBarcode);

		btnMinimize = new JButton(language.btnMinimize());
		btnMinimize.addActionListener(onMinimizeClick);
		btnMinimize.setFont(new Font("Times New Roman", Font.PLAIN, 18));
		btnMinimize.setBounds(303, 178, 130, 30);
		contentPane.add(btnMinimize);

		JToolBar toolBar = new JToolBar();
		toolBar.setRollover(true);
		toolBar.setFloatable(false);
		toolBar.setEnabled(false);
		toolBar.setBounds(0, 272, 634, 29);
		contentPane.add(toolBar);

		lblServerState = new JLabel("");
		toolBar.add(lblServerState);
		lblServerState.setFont(new Font("Tahoma", Font.PLAIN, 20));
	}

	private ActionListener onMinimizeClick = new ActionListener() {

		@Override
		public void actionPerformed(ActionEvent e) {
			MySystemTray.getInstace().setMinimize();
		}
	};

	private void updateLanguages() {
		language = LanguageFactory.getInstance().getLanguage();
		menuLanguages.setText(language.menuLanguage());
		menuPickNetworkCard.setText(language.menuPickNetworkCard());
		menuListDevide.setText(language.menuListDevide());
		menuExit.setText(language.btnExit());
		menuHelp.setText(language.menuHelp());
		menuHelpContents.setText(language.menuHelpContents());
		menuAbout.setText(language.menuAbout());
		lblPassword.setText(language.lblPassword());
		lblPort.setText(language.lblPort());
		lblIpAddress.setText(language.lblIpAddress());
		menuOption.setText(language.menuOption());
		btnStartServer.setText(language.btnStartServer());
		btnStopServer.setText(language.btnStopServer());
		lblHostName.setText(language.lblHostName());
		btnMinimize.setText(language.btnMinimize());

		rdbAutomatic.setText(language.menuScaleAutomatic());
		rdbBlanced.setText(language.menuScaleBlanced());
		rdbQuality.setText(language.menuScaleQuality());
		rdbSpeed.setText(language.menuScaleSpeed());
		rdbUltraQuality.setText(language.menuScaleUltraQuality());
		menuImageQuality.setText(language.menuScaleMathod());
		cbSaveImages.setText(language.menuSaveImages());
		menuPictureFrame.setText(language.menuPictureFrame());
	}

	public static void updateServerInfos() {
		// get Barcode
		try {
			serverInfo = NetworkUtil.getServerInfo();
			txtHostName.setText(serverInfo.getHostname());
			txtIPAddress.setText(serverInfo.getIpAddress());
			txtPassword.setText(serverInfo.getPassword());
			txtPort.setText(serverInfo.getPort() + "");
			bufferedImage = BarcodeUtil.encode(serverInfo);
			barcode = new ImageIcon(bufferedImage);
			lblBarcode.setIcon(barcode);
			// ---------------------------------------
		} catch (ClassNotFoundException | IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	private ActionListener onClickStopButton = new ActionListener() {

		@Override
		public void actionPerformed(final ActionEvent e) {
			if (server != null) {
				if (server.isStarted()) {
					try {
						server.stop();
						btnMinimize.setVisible(false);
						btnStartServer.setVisible(true);
						lblServerState.setText("");
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
				server = null;
			}
		}
	};
	private ActionListener onCLickStartButton = new ActionListener() {

		@Override
		public void actionPerformed(final ActionEvent e) {
			lblServerState.setText("Server is Ready!");
			if (server == null) {
				try {
					server = new Server(ServerGUI.this, serverInfo);
					server.start();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			} else {
				if (server.isStarted()) {
					JOptionPane.showMessageDialog(ServerGUI.this,
							"Server is running");
				} else if (!server.isStarted()) {
					try {
						server.start();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
			}
		}
	};
	public static JLabel lblServerState;
}
